package services

import (
    "encoding/json"
    "fmt"
    "path"
    "volux/models"
    "volux/utils"
    "github.com/beego/beego/v2/core/logs"
)

type StorageService struct {
    etcd *utils.EtcdClient
}

const (
    BdevPrefix      = "/volux/bdevs/"
    SubsystemPrefix = "/volux/subsystems/"
    NamespacePrefix = "/volux/namespaces/"
    ListenerPrefix  = "/volux/listeners/"
    HostPrefix      = "/volux/hosts/"
)

func NewStorageService(etcd *utils.EtcdClient) *StorageService {
    return &StorageService{etcd: etcd}
}

// StoreBdev 存储Bdev信息
func (s *StorageService) StoreBdev(bdev models.Bdev) error {
    logs.Info("%s Storing bdev information: %s", utils.LogStorage, bdev.Name)
    data, err := json.Marshal(bdev)
    if (err != nil) {
        return err
    }
    return s.etcd.Put(fmt.Sprintf("/bdevs/%s", bdev.Name), string(data))
}

// StoreSubsystem 存储Subsystem信息
func (s *StorageService) StoreSubsystem(nqn string, subsystem interface{}) error {
    data, err := json.Marshal(subsystem)
    if err != nil {
        return err
    }
    
    key := path.Join(SubsystemPrefix, nqn)
    return s.etcd.Put(key, string(data))
}

// StoreNamespace 存储Namespace信息
func (s *StorageService) StoreNamespace(nqn string, nsid uint32, namespace interface{}) error {
    data, err := json.Marshal(namespace)
    if err != nil {
        return err
    }
    
    key := path.Join(NamespacePrefix, nqn, fmt.Sprintf("%d", nsid))
    return s.etcd.Put(key, string(data))
}

// StoreListener 存储Listener信息
func (s *StorageService) StoreListener(nqn string, listener interface{}) error {
    data, err := json.Marshal(listener)
    if err != nil {
        return err
    }
    
    listenerMap, ok := listener.(map[string]interface{})
    if !ok {
        return fmt.Errorf("invalid listener format")
    }
    
    addr, ok := listenerMap["address"].(map[string]interface{})
    if !ok {
        return fmt.Errorf("invalid listener address format")
    }
    
    key := path.Join(ListenerPrefix, nqn, fmt.Sprintf("%s_%s", addr["traddr"], addr["trsvcid"]))
    return s.etcd.Put(key, string(data))
}

// StoreHost 存储Host信息
func (s *StorageService) StoreHost(nqn string, host interface{}) error {
    data, err := json.Marshal(host)
    if err != nil {
        return err
    }
    
    hostMap, ok := host.(map[string]interface{})
    if !ok {
        return fmt.Errorf("invalid host format")
    }
    
    hostNQN, ok := hostMap["nqn"].(string)
    if !ok {
        return fmt.Errorf("invalid host NQN format")
    }
    
    key := path.Join(HostPrefix, nqn, hostNQN)
    return s.etcd.Put(key, string(data))
}

// GetBdev 获取Bdev信息
func (s *StorageService) GetBdev(name string) (*models.Bdev, error) {
    data, err := s.etcd.Get(fmt.Sprintf("/bdevs/%s", name))
    if err != nil {
        return nil, err
    }

    var bdev models.Bdev
    if err := json.Unmarshal([]byte(data), &bdev); err != nil {
        return nil, err
    }
    return &bdev, nil
}

// GetBdevs 获取所有Bdev信息
func (s *StorageService) GetBdevs() ([]interface{}, error) {
    return s.getResources(BdevPrefix)
}

// GetSubsystems 获取所有Subsystem信息
func (s *StorageService) GetSubsystems() ([]interface{}, error) {
    return s.getResources(SubsystemPrefix)
}

// 通用的资源获取方法
func (s *StorageService) getResources(prefix string) ([]interface{}, error) {
    resp, err := s.etcd.GetWithPrefix(prefix)
    if err != nil {
        return nil, err
    }

    var resources []interface{}
    for _, event := range resp {
        var resource interface{}
        // 使用正确的字段访问
        if err := json.Unmarshal([]byte(event.Kv.Value), &resource); err != nil {
            return nil, err
        }
        resources = append(resources, resource)
    }
    
    return resources, nil
}

// DeleteBdev 从etcd删除Bdev信息
func (s *StorageService) DeleteBdev(name string) error {
    key := path.Join(BdevPrefix, name)
    return s.etcd.Delete(key)
}

// DeleteSubsystem 从etcd删除Subsystem及相关资源信息
func (s *StorageService) DeleteSubsystem(nqn string) error {
    // 删除子系统本身
    if err := s.etcd.Delete(path.Join(SubsystemPrefix, nqn)); err != nil {
        return err
    }
    
    // 删除相关的命名空间
    if err := s.etcd.DeleteWithPrefix(path.Join(NamespacePrefix, nqn)); err != nil {
        return err
    }
    
    // 删除相关的监听器
    if err := s.etcd.DeleteWithPrefix(path.Join(ListenerPrefix, nqn)); err != nil {
        return err
    }
    
    // 删除相关的主机配置
    if err := s.etcd.DeleteWithPrefix(path.Join(HostPrefix, nqn)); err != nil {
        return err
    }
    
    return nil
}

// DeleteNamespace 从etcd删除Namespace信息
func (s *StorageService) DeleteNamespace(nqn string, nsid uint32) error {
    key := path.Join(NamespacePrefix, nqn, fmt.Sprintf("%d", nsid))
    return s.etcd.Delete(key)
}

// DeleteListener 从etcd删除Listener信息
func (s *StorageService) DeleteListener(nqn string, traddr string, trsvcid string) error {
    key := path.Join(ListenerPrefix, nqn, fmt.Sprintf("%s_%s", traddr, trsvcid))
    return s.etcd.Delete(key)
}

// DeleteHost 从etcd删除Host信息
func (s *StorageService) DeleteHost(nqn string, hostNQN string) error {
    key := path.Join(HostPrefix, nqn, hostNQN)
    return s.etcd.Delete(key)
}
